/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frreport_dbg.c                                     */
/*  NOTE      = 测试代码                                       */
/*  DATE      = 2014/12/05                                         */
/*******************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>

#include "frcomm.h"
#include "frlog.h"
#include "frmem.h"
#include "frlist.h"

#include "conntrack.h"
#include "module.h"
#include "frreport_comm.h"
#include "frreport_params.h"

#include "frreport_dbg.h"

//#define FRDBG_REPORT_ALL 1
//#define FRDBG_REPORT_SHOW 1

//#if defined(FRDBG_REPORT_TESTTOOLS) || defined(FRDBG_REPORT_FILE) || defined(FRDBG_REPORT_SHOW)

    /*******************************************************************************
    *  FUNC     :  Frreport_data数据转换成字符串
    *  ARGS     :  p_st_report_data (Frreport_data *)
    *           :  i_flag_style     (FR_YES:格式化输出; FR_NO:无格式化输出)
    *           :  pp_data_out      (formate后数据)
    *           :  p_ui_data_len    (数据长度)
    *  RTN      :  成功:FR_SUCC; 失败:FR_FAIL
    *  NOTE     :  调试用接口
    *******************************************************************************/
    int frdbg_report_data_format(Frreport_data *p_st_report_data
                                , int i_flag_style
                                , char **pp_data_out
                                , unsigned int *p_ui_data_len)
    {
        if(p_st_report_data == NULL
           || pp_data_out == NULL || p_ui_data_len == NULL)
            return FR_FAIL;

        *pp_data_out = frreport_data_output(p_st_report_data, i_flag_style);
        if(*pp_data_out)
            *p_ui_data_len = strlen(*pp_data_out)+1;
        else
            *p_ui_data_len = 0;

        return FR_SUCC;
    }

     /*******************************************************************************
    *  FUNC     :  取得重命名文件名
    *  ARGS     :  p_oldname (旧文件名)
    *               :  p_newname (新文件名)
    *  RTN      :  成功:FR_SUCC; 失败:FR_FAIL
    *  NOTE     :
    *******************************************************************************/
    int frdbg_rename_filename(const char *p_oldname, char **p_newname)
    {
    	int i_len = strlen(p_oldname);
    	const char *p_filename = NULL;
    	char *p_name = NULL;
    	const char *p_dot = NULL;

    	//取得文件名
    	p_filename = strrchr(p_oldname, '/');
    	p_filename++;

    	//取得文件名前缀(.前面部分)
    	p_dot = strchr(p_filename, '.');

    	//长度3('_1' + '\0')
    	p_name = (char *)frmalloc(i_len + 3);
    	if (p_name == NULL)
    		return FR_FAIL;
    	memset(p_name, 0x00, i_len + 3);

    	//文件目录部分
    	strncpy(p_name, p_oldname, i_len - strlen(p_filename));
    	//.前部分
    	strncat(p_name, p_filename, p_dot - p_filename);
    	strcat(p_name, "_1");
        strcat(p_name, p_dot);

    	*p_newname = p_name;

    	return FR_SUCC;
    }


    void frdbg_report_data_write(const char *p_filename, const char *p_data, unsigned int ui_data_len)
    {
        FILE *pFile=NULL;
        char arr_len[20];
        char *p_new_name = NULL;
        struct stat buffer;
        int i_rtn = 0;

        if(p_filename == NULL || *p_filename == '\0' || p_data == NULL || ui_data_len<= 0)
            return;

        pFile = fopen(p_filename , "ab+");
        if(pFile == NULL)
            return;

        //取得文件大小
        if (stat(p_filename, &buffer) < 0)
        {
        	fclose(pFile);
        	return;
        }

        //文件超过指定最大长，将文件重命名，建新文件
        if ((buffer.st_size + ui_data_len)/1024 > st_report_params.ui_file_maxsize)
        {
        	fclose(pFile);
        	//取得重命名文件名
        	i_rtn = frdbg_rename_filename(p_filename, &p_new_name);
        	if (i_rtn == FR_FAIL)
        		return;
        	//文件重命名
        	i_rtn = rename(p_filename, p_new_name);
        	if (i_rtn < 0)
        	{
        		frfree(p_new_name);
        		return;
        	}
		frfree(p_new_name);
		//重新打开文件
        	pFile = fopen(p_filename , "ab+");
        	if (pFile == NULL)
            		return;
        }

        snprintf(arr_len, sizeof(arr_len), "%u:", ui_data_len);
        fwrite(arr_len, 1, strlen(arr_len), pFile);
        fwrite(p_data, 1, ui_data_len, pFile);

        //增加空行
        fwrite("\n", 1, 1, pFile);

        fclose(pFile);

        return;
    }

    void frdbg_report_data_send_udp(const char *p_srv_ip, unsigned int ui_srv_port, const char *p_data, unsigned int ui_data_len)
    {
        int i_sockfd;
        struct sockaddr_in st_toAddr;
        int i_ret_fun=0;

        char arr_len[20];

        if(p_srv_ip == NULL || *p_srv_ip == '\0' || ui_srv_port <= 0
           || p_data == NULL || ui_data_len<= 0)
            return;

        i_sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if (i_sockfd < 0)
        {
            FRLOG_ERROR_DETAIL("socket err(ip=%s port=%u)", p_srv_ip, ui_srv_port);
            return;
        }

        memset(&st_toAddr,0,sizeof(st_toAddr));
        st_toAddr.sin_family=AF_INET;
        st_toAddr.sin_addr.s_addr=inet_addr(p_srv_ip);
        st_toAddr.sin_port = htons(ui_srv_port);

        snprintf(arr_len, sizeof(arr_len), "%u:", ui_data_len);
        i_ret_fun = sendto(i_sockfd, arr_len, strlen(arr_len), 0, (struct sockaddr*)&st_toAddr,sizeof(st_toAddr));
        if(i_ret_fun != strlen(arr_len))
            FRLOG_WARN_DETAIL("socket data maybe lost(ip=%s port=%u)", p_srv_ip, ui_srv_port);
        i_ret_fun = sendto(i_sockfd, p_data, ui_data_len, 0, (struct sockaddr*)&st_toAddr,sizeof(st_toAddr));
        if(i_ret_fun != ui_data_len)
            FRLOG_WARN_DETAIL("socket data maybe lost(ip=%s port=%u)", p_srv_ip, ui_srv_port);
        close(i_sockfd);

        return;
    }

    void frdbg_report_data_send_tcp(const char *p_srv_ip, unsigned int ui_srv_port, const char *p_data, unsigned int ui_data_len)
    {
        int i_sockfd;
        struct sockaddr_in st_toAddr;
        int i_ret_fun=0;
        struct in_addr st_inaddr;
        char arr_len[20];
        struct timeval st_timeout = {2, 0};
        socklen_t u_len = sizeof(st_timeout);

        if(p_srv_ip == NULL || *p_srv_ip == '\0' || ui_srv_port <= 0
           || p_data == NULL || ui_data_len<= 0)
            return;

        i_sockfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
        if (i_sockfd < 0)
        {
            FRLOG_ERROR_DETAIL("socket err(ip=%s port=%u)(%s)", p_srv_ip, ui_srv_port, strerror(errno));
            return;
        }
        setsockopt(i_sockfd, SOL_SOCKET, SO_SNDTIMEO, &st_timeout, u_len);

        inet_aton(p_srv_ip,&st_inaddr);
        memset(&st_toAddr,0,sizeof(st_toAddr));
        st_toAddr.sin_family=AF_INET;
        st_toAddr.sin_addr=st_inaddr;
        st_toAddr.sin_port = htons(ui_srv_port);

        if(connect(i_sockfd, (struct sockaddr *)&st_toAddr, sizeof(struct sockaddr))==-1)
        {
            FRLOG_ERROR_DETAIL("connect err(ip=%s port=%u)(%s)", p_srv_ip, ui_srv_port, strerror(errno));
            return;
        }

        snprintf(arr_len, sizeof(arr_len), "%u:", ui_data_len);
        i_ret_fun = send(i_sockfd, arr_len, strlen(arr_len), 0);
        if(i_ret_fun != strlen(arr_len))
            FRLOG_WARN_DETAIL("socket data maybe lost(ip=%s port=%u)(%s)", p_srv_ip, ui_srv_port, strerror(errno));
        i_ret_fun = send(i_sockfd, p_data, ui_data_len, 0);
        if(i_ret_fun != ui_data_len)
            FRLOG_WARN_DETAIL("socket data maybe lost(ip=%s port=%u)(%s)", p_srv_ip, ui_srv_port, strerror(errno));
        close(i_sockfd);

        return;
    }

//#endif
